#pragma once
#include <grpcpp/grpcpp.h>			

#include "message.grpc.pb.h" //grpc的业务的头文件，由GRPC生成的对应的平台而使用
#include "const.h"
#include "Singleton.h"
#include <queue>
#include <memory>
#include "ConfigMgr.h"

using grpc::Channel;
using grpc::Status;
using grpc::ClientContext;

using message::GetVarifyReq;
using message::GetVarifyRsp;
using message::VarifyService;


//负责传递远程调用到远程的服务器接口，提供给控制层使用，属于View层的一种吧，但是其实也有点view层的感觉
//严格意义上来说，提供远程接口调用的能力，shuyu View层


class RPConPool;
//RPC 连接池，可能存在多个RPC客户端的连接池进行使用
class RPConPool {
public:
	RPConPool(size_t poolSize, std::string host, std::string port);

	~RPConPool();

	std::unique_ptr<VarifyService::Stub> getConnection();


	void returnConnection(std::unique_ptr<VarifyService::Stub> context);

	void Close();

private:
	atomic<bool> b_stop_;
	size_t poolSize_;
	std::string host_;
	std::string port_;
	std::queue<std::unique_ptr<VarifyService::Stub>> connections_;
	std::mutex mutex_;
	std::condition_variable cond_;
};


//GRPC客户端
class VerifyGrpcClient :public Singleton<VerifyGrpcClient>
{
	friend class Singleton<VerifyGrpcClient>;
public:

	// 内部转发调用GRPC接口，提供法国内部接口所需参数
	GetVarifyRsp GetVarifyCode(std::string email);

private:
	VerifyGrpcClient();

	std::unique_ptr<VarifyService::Stub> stub_;			//信使，是一个媒介，只有通过它才可以通信，通过它传递参数到服务端进行调用

	std::unique_ptr<RPConPool> pool_;

};

/*
客户端：
* grpc 负责根据.proto文件生成对应的
* 1.服务调用接口，该服务接口由信使调用，参数还有返回值，参数通过值传递，返回值通过指针传递
从而生成客户端调用接口，通过思念是stub进行调用
2.grpc参数通过.proto文件生成对应的类和方法，可以使用set方法对其内容进行赋值，从而设置将要序列化传送的参数
3.参数和方法解耦合，参数通过序列化传送，方法在另外一端重新使用语言生成，序列化过去的对象也会反序列化
为该平台的数据对象



服务端：

*/
